<?php

class LikeModel
{
    private $likeKeyPrefix              =   'LI/';
    private $groupChatKeyPrefix         =   'GC/';
    private $groupChatUserKeyPrefix     =   'GU/';
    private $groupLinkKeyPrefix         =   'GL/';
    private $groupChatMessageKeyPrefix  =   'GCM/';
    private $likeMeType     =   1;
    private $meLikeType     =   2;
    private $familyGroup    =   1;
    private $collegeGroup   =   2;
    private $commonGroup    =   1;
    private $vipGroup       =   2;
    private $officialGroup  =   3;
    private $diaryListCacheModel;
    private $autoUidModel;
    
    function __construct()/*{{{*/
    {
        $this->diaryListCacheModel  =   new DiaryListCacheModel();
        $this->autoUidModel         =   new AutoUidModel();
    }

    private function getLikeInfo($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['lUid'])    ||  empty($info['bodyId'])  ||  empty($info['type']))
        {
            AC::$errorNo    =   'LIM009';
            return  FALSE;
        }

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   array(
                        'lUid'      =>  $info['lUid'],
                        'bodyId'    =>  $info['bodyId'],
                        'type'      =>  $info['type'],
                        'likeType'  =>  $info['likeType'],
                    );
        $result =   Storage::getConditionData($key, $where);
        return  $result;
    }/*}}}*/

    public function getLikeMeList($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM007';
            return  FALSE;
        }

        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   array('likeType' => $this->likeMeType);
        if (!empty($info['id']))    $where  =   ' id > '. $info['id']. ' AND `likeType` = '. $this->likeMeType. ' ';
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/
    public function getLikeMeListUp($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM007';
            return  FALSE;
        }
        if (empty($info['id'])) return  $this->getLikeMeList($info);

        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   ' id > '. $info['id']. ' AND `likeType` = '. $this->likeMeType. ' ';
        $orderBy=   ' id ASC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/
    public function getLikeMeListDown($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM007';
            return  FALSE;
        }
        if (empty($info['id'])) return  $this->getLikeMeList($info);

        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   ' id < '. $info['id']. ' AND `likeType` = '. $this->likeMeType. ' ';
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/

    public function getMeLikeList($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM006';
            return  FALSE;
        }

        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   array('likeType' => $this->meLikeType);
        if (!empty($info['id']))    $where  =   ' id > '. $info['id']. ' AND `likeType` = '. $this->meLikeType. ' ';
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/
    
    public function getMeLikeDiaryList($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM006';
            return  FALSE;
        }
    
        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['length'])  &&  $length =   $info['length'];
    
        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   array('likeType' => $this->meLikeType);
        if (intval($info['id']) > 0){    
            $where  =   ' id < '. $info['id']. ' AND `likeType` = '. $this->meLikeType. ' ';
        }
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/
    
    public function getMeLikeListUp($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM006';
            return  FALSE;
        }

        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   ' id > '. $info['id']. ' AND `likeType` = '. $this->meLikeType. ' ';
        $orderBy=   ' id ASC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/
    public function getMeLikeListDown($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'LIM006';
            return  FALSE;
        }

        $start  =   0;
        $length =   AC::LIKE_LIST_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   array('likeType' => $this->meLikeType);
        if (intval($info['id']) > 0){
            $where  =   ' id < '. $info['id']. ' AND `likeType` = '. $this->meLikeType. ' ';
        }
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/

    public function postLike($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['nickname'])||  empty($info['lUid'])    ||  empty($info['lNickname']))
        {
            AC::$errorNo    =   'LIM001';
            return  FALSE;
        }
        if (empty($info['type'])||  empty($info['bodyId']))
        {
            AC::$errorNo    =   'LIM002';
            return  FALSE;
        }
        if ($info['uid']    ==  $info['lUid'])
        {
            AC::$errorNo    =   'LIM008';
            return  FALSE;
        }
        if (AC::FEED_LIKE   ==  $info['type'])
        {
            AC::$errorNo    =   'LIM011';
            return  FALSE;
        }
        $info['likeType']   =   $this->meLikeType;
        
        /*
        $likeInfo   =   $this->getLikeInfo($info);
        if (!empty($likeInfo))
        {
            AC::$errorNo    =   'LIM010';
            return  FALSE;
        }
        */
        $isLiked = $this->checkIsLiked($info['uid'], $info['bodyId']);
        if ($isLiked) {
            AC::$errorNo    =   'LIM010';
            return  FALSE;
        }

        #   post MeLike /*{{{*/
        $dataMeLike     =   array(
                                'uid'       =>  $info['uid'],
                                'lUid'      =>  $info['lUid'],
                                'lNickname' =>  $info['lNickname'],
                                'bodyId'    =>  $info['bodyId'],
                                'type'      =>  $info['type'],
                                'content'   =>  $info['content'],
                                'likeType'  =>  $this->meLikeType,
                                'time'      =>  AC::SERVER_TIME,
                            );
        $meLikeKey      =   $this->likeKeyPrefix. $info['uid'];
        $meLikeResult   =   Storage::addData($meLikeKey, $dataMeLike);
        if (empty($meLikeResult))
        {
            AC::$errorNo    =   'LIM003';
            return  FALSE;
        }/*}}}*/

        $tmp = array(
                'bodyId'    =>    $info['bodyId'],
                'type'      =>    $info['type'],
                'uid'       =>    $info['lUid'],
                'lUid'      =>    $info['uid'],
                'likeType'  =>    $this->likeMeType
        );
        
        /*
        $lUlikeInfo   =   $this->getLikeInfo($tmp);
        if (!empty($lUlikeInfo))
        {
            AC::$errorNo    =   'LIM010';
            return  FALSE;
        }
        */
        $isLike = $this->checkIsLiked($info['lUid'], $info['bodyId']);
        if ($isLike) {
            AC::$errorNo    =   'LIM010';
            return  FALSE;
        }
        
        #   post LikeMe /*{{{*/
        $dataLikeMe     =   array(
                                'uid'       =>  $info['lUid'],
                                'lUid'      =>  $info['uid'],
                                'lNickname' =>  $info['nickname'],
                                'bodyId'    =>  $info['bodyId'],
                                'type'      =>  $info['type'],
                                'content'   =>  $info['content'],
                                'likeType'  =>  $this->likeMeType,
                                'time'      =>  AC::SERVER_TIME,
                            );
        $likeMeKey      =   $this->likeKeyPrefix. $info['lUid'];
        $likeMeResult   =   Storage::addData($likeMeKey, $dataLikeMe);
        if (empty($likeMeResult))
        {
            AC::$errorNo    =   'LIM004';
            return  FALSE;
        }/*}}}*/

        return  TRUE;
    }/*}}}*/
    
    /**
     * 判断是否喜欢某个日记
     * @param unknown $uid
     * @param unknown $bodyId
     * @return boolean
     */
    private function checkIsLiked ($uid, $bodyId) {
        if (empty($uid) || empty($bodyId)) return FALSE;
        
        $meLikes = $this->diaryListCacheModel->getMeLikesList($uid, 0, -1);
        if ($meLikes) {
            $flushTime = $this->meLikeFlushTimeIsExisted($uid);
            if (!$flushTime) {
                $this->diaryListCacheModel->updateUserFlushTimeCache($uid, $data = array('ld_t' => AC::SERVER_TIME));
            }
        }else{
            $meLikes = $this->rebuildMeLikeList($uid);
        }
        
        if (in_array($bodyId, $meLikes)) {
            return TRUE;
        }
        
        return FALSE;
    }
    
    /**
     * 判断是否记录了更新时间
     * @param unknown $uid
     * @return boolean
     */
    private function meLikeFlushTimeIsExisted ($uid) {
        $flushTime = $this->diaryListCacheModel->getUserFlushTimeCache($uid);
        if (!isset($flushTime['ld_t']) || empty($flushTime['ld_t'])) {
            return FALSE;
        }
        
        return TRUE;
    }
    
    /**
     * 重建我的喜欢列表
     * @param unknown $uid
     * @return boolean|multitype:Ambigous <>
     */
    private function rebuildMeLikeList ($uid) {
        if (empty($uid)) {
            AC::$errorNo    =   'LIM006';
            return  FALSE;
        }
        
        $key    =   $this->likeKeyPrefix. $uid;
        $where  =   array('likeType' => $this->meLikeType);
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy);
        $bodyIds=   array();
        if ($result) {
            
            foreach ($result as $value) {
                $bodyIds[] = $value['bodyId'];
                $this->diaryListCacheModel->addMeLikesList($uid, $value['bodyId']);
            }
            $this->diaryListCacheModel->updateUserFlushTimeCache($uid, $data = array('ld_t' => AC::SERVER_TIME));
        }
        
        return  $bodyIds;
    }
    
    /**
     * 查找某日记是否喜欢
     * @param unknown $uid
     * @param unknown $bodyId
     * @param unknown $type
     * @return boolean|Ambigous <multitype:, unknown, boolean>
     */
    public function findMeLikeInfo($uid, $bodyId, $type){
        if (empty($uid)) {
            AC::$errorNo    =   'LIM005';
            return  FALSE;
        }
        $key    =   $this->likeKeyPrefix. $uid;
        $where  =   array('type' => $type,'bodyId'=>$bodyId);
        $result =   Storage::getConditionData($key, $where);
        
        return $result;
    }
    
    public function removeLike($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['bodyId']))
        {
            AC::$errorNo    =   'LIM005';
            return  FALSE;
        }

        $key    =   $this->likeKeyPrefix. $info['uid'];
        $where  =   array('bodyId' => $info['bodyId']);
        $result =   Storage::delConditionData($key, $where);

        $key    =   $this->likeKeyPrefix. $info['lUid'];
        $where  =   array('bodyId' => $info['bodyId']);
        $result =   Storage::delConditionData($key, $where);
        return  $result;
    }/*}}}*/

    public function getLikeById($id,$uid)/*{{{*/
    {
        if (empty($id) || empty($uid))
        {
            AC::$errorNo    =   'LIM009';
            return  FALSE;
        }
    
        $key    =   $this->likeKeyPrefix. $uid;
        $where  =   array('id'=>$id,'likeType'=>$this->meLikeType);
        $result =   Storage::getConditionData($key, $where);
        return  $result;
    }/*}}}*/
    
    public function getLikeByBodyId($bodyId,$uid)/*{{{*/
    {
        if (empty($bodyId) || empty($uid))
        {
            AC::$errorNo    =   'LIM009';
            return  FALSE;
        }
    
        $key    =   $this->likeKeyPrefix. $uid;
        $where  =   array('bodyId'=>$bodyId, 'likeType'=>$this->meLikeType);
        $result =   Storage::getConditionData($key, $where);
        return  $result;
    }/*}}}*/
    
    /**
     * 我(创建/加入/申请)的群列表
     * @param unknown $uid
     * @param unknown $start
     * @param unknown $length
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function getGroupsByUid($uid, $role = 0, $status = 1, $start = 0, $length = 20){
        $key      =   $this->groupLinkKeyPrefix. $uid;
        $where    =   array('uid' => $uid, 'role' => $role, 'status' => $status, 'type' => 1);
        if (empty($role)){
            $where = " uid = '".$uid."' AND status = 1 AND type = 1 AND role >= 0";
        }
        $orderBy  =   ' id DESC ';
        $result   =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }

    public function getJoinedGroups($uid){
        $key      =   $this->groupLinkKeyPrefix. $uid;
        $where    =   array('uid' => $uid, 'status' => 1, 'type' => 1);
        $orderBy  =   ' id DESC ';
        $result   =   Storage::getConditionManyData($key, $where, $orderBy);
        return  $result;
    }
    
    /**
     * 创建群聊
     * @param unknown $param
     * @return boolean|Ambigous <unknown, boolean, number, resource>
     */
    public function createChatGroup($param){
        $key      =   $this->groupChatKeyPrefix. 0;
        $result   =   Storage::addData($key, $param);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }/*}}}*/
    
        return  $result;
    }
    
    /**
     * 加入成员信息表
     * @param unknown $remark
     * @param unknown $uid
     * @return boolean|Ambigous <unknown, boolean, number, resource>
     */
    public function joinChatGroup($remark, $uid, $gid){
        $data = array(
                'uid'        =>    $uid,
                'gid'        =>    $gid,
                'remark'     =>    strval($remark),
                'time'       =>    AC::SERVER_TIME,
        );
    
        $key      =   $this->groupChatUserKeyPrefix. $uid;
        
        // 读取
        $where    =   array('uid' => $uid, 'gid' => $gid);
        $info     =   Storage::getConditionData($key, $where);
        if (empty($info)){
            $result   =   Storage::addData($key, $data);
            if (empty($result))
            {
                AC::$errorNo    =   'LGM002';
                return  FALSE;
            }/*}}}*/
        }else{
            $tmp = array('time' => AC::SERVER_TIME);
            $result   =   Storage::setConditionData($key, $tmp, $where);
            $result = $info['id'];
        }
        
        $this->diaryListCacheModel->addUserToChatGroup($uid, $gid);
        $this->diaryListCacheModel->addOneToUserChatGroups($gid, $uid);
        return  $result;
    }
    
    /**
     * 加入到成员与群的关系表,按uid,gid分别分表
     * @param unknown $gid
     * @param unknown $linkid
     * @param unknown $status
     * @param unknown $role
     * @return boolean|Ambigous <unknown, boolean, number, resource>
     */
    public function addGroupChatLink($gid, $linkid, $author_uid, $status, $role, $content = ''){
        $data1 = array(
                'uid'        =>    AC::HOST_UID,
                'gid'        =>    intval($gid),
                'linkid'     =>    intval($linkid),
                'author_uid' =>    intval($author_uid),
                'status'     =>    intval($status),
                'role'       =>    intval($role),
                'type'       =>    1,
                'content'    =>    $content,
                'time'       =>    AC::SERVER_TIME
        );
        $key      =   $this->groupLinkKeyPrefix. AC::HOST_UID;
        $result   =   Storage::addData($key, $data1);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }/*}}}*/
    
        $data2 = array(
                'uid'        =>    AC::HOST_UID,
                'gid'        =>    intval($gid),
                'linkid'     =>    intval($linkid),
                'author_uid' =>    intval($author_uid),
                'status'     =>    intval($status),
                'role'       =>    intval($role),
                'type'       =>    2,
                'content'    =>    $content,
                'time'       =>    AC::SERVER_TIME
        );
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $result   =   Storage::addData($key, $data2);
    
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }/*}}}*/
    
        return  TRUE;
    }
    
    /**
     * 编辑群信息
     * @param unknown $param
     * @param unknown $gid
     * @return boolean|Ambigous <boolean, unknown, number, resource>
     */
    public function editChatGroupInfo($param, $gid){
        $key      =   $this->groupChatKeyPrefix. 0;
        $where    =   array('gid' => $gid);
        $result   =   Storage::setConditionData($key, $param, $where);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }/*}}}*/

        $this->diaryListCacheModel->delMysqlDataHashCache("ChatGroup", $gid);
        return  TRUE;
    }
    
    public function setChatGroupMemebers($data, $gid){
        $key      =   $this->groupChatKeyPrefix. 0;
        $where    =   array('gid' => $gid);
        $result =   Storage::changeNumValueAdd($key, $data, $where);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }/*}}}*/
        
        $this->diaryListCacheModel->setCount('ChatGroup', $gid, "member_num", $data['member_num']);
        return  TRUE;
    }
    
    /**
     * 所有群
     * @param unknown $uid
     * @param unknown $start
     * @param unknown $length
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function allChatGroups($start, $length, $recomment = 0, $gtype = 0, $id = 0){
        $key      =   $this->groupChatKeyPrefix. 0;
        $where    =   " status = 0 ";
        
        if ($id > 0){
            $start = 0;
            $where .= " AND gid < ".$id;
        }

        if ($gtype > 0 && in_array($gtype, array($this->commonGroup, $this->vipGroup, $this->officialGroup))) {
            if ($gtype==1)
                $where .= ' AND `type` IN (1,2) ';
            else
                $where    .=   " AND type = ".$gtype;
        }
        
        // 获取推荐群组
        if($recomment > 0){
            $where    .=   " AND attribute in (1,2) ";
        }
        
        $orderBy  =   ' display DESC, gid DESC';
        if ($id > 0) $orderBy  =   ' gid DESC';
        
        $result   =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }
    
    /**
     * 搜索群
     * @param unknown $name
     * @param unknown $start
     * @param unknown $length
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function searchChatGroupsByName($name, $start, $length, $id){
        $key      =   $this->groupChatKeyPrefix. 0;
        $where    =   " name like '%".$name."%' AND status = 0";
        if ($id > 0){
            $start = 0;
            $where .= " AND gid < ".$id;
        }
        $orderBy  =   ' gid DESC';
        $result     =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }
    
    /**
     * 查看群信息
     * @param unknown $gid
     * @param number $status
     * @return multitype:string
     */
    public function getChatGroupInfoByGid($gid, $status = 0){
        // 获取群信息缓存
        $info = $this->diaryListCacheModel->getMysqlDataHashCache('ChatGroup', $gid);
        if (empty($info)){
            $key      =   $this->groupChatKeyPrefix. 0;
            $where    =   array('gid' => $gid, 'status' => $status);
            $info     =   Storage::getConditionData($key, $where);
            $this->diaryListCacheModel->setMysqlDataHashCache('ChatGroup', $gid, $info);
        }
        if (empty($info)){
            return array();
        }
        $result   =   $this->structureChatGroupData($info, AC::HOST_UID);
        return  $result;
    }

    public function getChatGroupDetail($gid){
        if (empty($gid)) return false;

        $result = $this->diaryListCacheModel->getMysqlDataHashCache('ChatGroup', $gid);
        if (empty($result)){
            $key      =   $this->groupChatKeyPrefix. 0;
            $where    =   array('gid' => $gid, 'status' => 0);
            $result     =   Storage::getConditionData($key, $where);
            $this->diaryListCacheModel->setMysqlDataHashCache('ChatGroup', $gid, $result);
        }
        if (empty($result)){
            return array();
        }

        return  $result;
    }

    public function getUserJoinedChatGroupIds($uid)
    {
        if (empty($uid)) return array();

        $key      =   $this->groupLinkKeyPrefix. $uid;
        $where  =   array('uid' => $uid, 'type' => 1, 'status' => 1);

        $result =   Storage::getConditionManyData($key, $where);
        return  $result;
    }

    public function getChatGroupMemberIds($gid)
    {
        if (empty($gid)) return array();

        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where  =   array('gid' => $gid, 'type' => 2, 'status' => 1);

        $result =   Storage::getConditionManyData($key, $where);
        return  $result;
    }
    
    /**
     * 查询某个群中某个用户
     * @param unknown $uid
     * @param unknown $gid
     * @param unknown $status
     * @return Ambigous <multitype:, unknown, boolean, mixed>
     */
    public function getGroupUserLinkInfo($uid, $gid, $status = 0){
        $key      =   $this->groupLinkKeyPrefix. $uid;
        $where  =   array('gid' => $gid, 'uid' => $uid,'status' => $status,'type' => 1);
        if (empty($status)){
            $where = " uid = '".$uid."' AND gid = '".$gid."' AND type = 1";
        }
        $result =   Storage::getConditionData($key, $where);
        return  $result;
    }
    
    /**
     * 更改群中所有用户的状态
     * @param unknown $gid
     * @return boolean
     */
    public function setGroupAllUserStatus($gid){
        for($i=0;$i<=7;$i++)
        {
            $sql        = 	"Update xxtLike.grouplink_".$i." SET status = 5 WHERE gid = ".$gid;
            $keyClient  =   $this->groupLinkKeyPrefix. $i;
            $result     =   Storage::fetchDbSentenceByClient($keyClient, $sql, 2);
        }
        $this->diaryListCacheModel->delChatGroupAllUsers($gid);
        return  true;
    }
    
    /**
     * 查看群成员列表
     * @param unknown $gid
     * @param unknown $start
     * @param unknown $length
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function getLinkInfoByGid($gid, $start, $length){
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where    =   " gid = ".$gid." AND status = 1 AND type = 2 AND role != 1 ";
        $orderBy  =   ' role DESC, time DESC ';
        $result   =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }
    
    public function getAllUsersByGid($gid){
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where    =   " gid = ".$gid." AND status = 1 AND type = 2 ";
        $orderBy  =   ' id DESC ';
        $result   =   Storage::getConditionManyData($key, $where, $orderBy);
        return  $result;
    }
    
    /**
     * 获取所有群用户
     * @param unknown $gid
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function getGidUsers($gid){
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where    =   array('gid' => $gid, 'status' => 1, 'type' => 2);
        $orderBy  =   ' role DESC, time DESC ';
        $result   =   Storage::getConditionManyData($key, $where, $orderBy);
        return  $result;
    }
    
    /**
     * 查询群中管理员
     * @param unknown $gid
     * @return Ambigous <Num, boolean, number>
     */
    public function getChatGroupAdmins($gid){
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where    =   " gid = ".$gid." AND status = 1 AND type = 2 AND role = 2 ";
        $result   =   Storage::getConditionManyData($key, $where);
        return $result;
    }
    
    /**
     * 查询某个群中某个用户具体信息
     * @param unknown $uid
     * @param unknown $linkid
     * @param unknown $status
     * @return multitype:string
     */
    public function getChatUserInfoById($uid, $link, $group){
        $gid         = $group['gid'];
        $attribute   = $group['attribute'];
        $linkid      = $link['linkid'];
        $role        = $link['role'];
        if (empty($uid) || empty($linkid) || empty($gid)) return array();
        
        $info = $this->diaryListCacheModel->getMysqlDataHashCache("ChatUser", $gid."_".$uid);
        if (empty($info)){
            $key      =   $this->groupChatUserKeyPrefix. $uid;
            $where    =   array('id' => $linkid);
            $info     =   Storage::getConditionData($key, $where);
            $this->diaryListCacheModel->setMysqlDataHashCache("ChatUser", $gid."_".$uid, $info);
        }
        if (empty($info)){
            return array();
        }
        $result   =   $this->structureChatUserData($info, $uid, $role, $attribute);
        return  $result;
    }
    
    /**
     * 修改在群中的信息
     * @param unknown $uid
     * @param unknown $linkid
     * @param unknown $remark
     */
    public function setGroupUserData($uid, $linkid, $data, $gid){
        $key      =   $this->groupChatUserKeyPrefix. $uid;
        $where    =   array('id' => $linkid);
        $result   =   Storage::setConditionData($key, $data, $where);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }
        
        // 修改缓存
        $this->diaryListCacheModel->setMysqlDataHashCache('ChatUser', $gid."_".$uid, $data);
        return  TRUE;
    }
    
    /**
     * 发言数加1
     * @param unknown $uid
     * @param unknown $gid
     * @param unknown $data
     * @param unknown $linkid
     * @return boolean
     */
    public function setGroupUserChatNum($uid, $gid, $data, $linkid){
        $key      =   $this->groupChatUserKeyPrefix. $uid;
        $where    =   array('id' => $linkid);
        $result =   Storage::changeNumValueAdd($key, $data, $where);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }/*}}}*/
    
        $this->diaryListCacheModel->setCount("ChatUser", $gid."_".$uid, "chat_num", 1);
        return  TRUE;
    }
    
    /**
     * 通过群名查群信息
     * @param unknown $name
     * @param unknown $gid
     * @return Ambigous <multitype:, unknown, boolean, mixed>
     */
    public function getGroupInfoByName($name, $gid = 0){
        $key      =   $this->groupChatKeyPrefix. 0;
        $where  =   array('name'=>$name, 'status'=>0);
        if ($gid > 0){
            $where  =   " gid != '".$gid."' AND status = '0' AND name = '".$name."'";
        }
        $result =   Storage::getConditionData($key, $where);
        return  $result;
    }
  
    /**
     * 修改Link表数据
     * @param unknown $uid
     * @param unknown $gid
     * @param unknown $data
     * @return boolean
     */
    public function setChatGroupLinkInfo($uid, $gid, $data){
        $key      =   $this->groupLinkKeyPrefix. $uid;
        $where    =   array('uid' => $uid, 'gid' => $gid, 'type' => 1);
        $result   =   Storage::setConditionData($key, $data, $where);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }
        
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where    =   array('uid' => $uid, 'gid' => $gid, 'type' => 2);
        $result   =   Storage::setConditionData($key, $data, $where);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }
        
        // 删除缓存
        if ($data['status'] == AC::CHAT_GROUP_QUIT_STATUS || $data['status'] == AC::CHAT_GROUP_FIRE_STATUS){
            $this->diaryListCacheModel->delChatGroupUser($uid, $gid);
            $this->diaryListCacheModel->delOneFromUserChatGroups($gid, $uid);
            $this->diaryListCacheModel->delMysqlDataHashCache("ChatUser", $gid."_".$uid);
        }
        return  TRUE;
    }
    
    /**
     * 群未处理事项
     * @param unknown $uid
     * @param unknown $gid
     * @param unknown $start
     * @param unknown $length
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function getPendingRequests($uid, $gid, $start, $length, $id = 0){
        $key      =   $this->groupLinkKeyPrefix. $gid;
        $where    =   " type = '2' AND status = '4' AND author_uid = '".$uid."'";
        if ($id > 0){
            $start = 0;
            $where .= " AND id < ".$id;
        }
        $orderBy  =   ' id DESC ';
        $result   =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }
    
    /**
     * 群聊天
     * @param unknown $data
     * @return Ambigous <unknown, boolean, number, resource>
     */
    public function postGroupChat($data){
        $key    =   $this->groupChatMessageKeyPrefix. $data['gid'];
        $result =   Storage::addData($key, $data);
        if (empty($result))
        {
            AC::$errorNo    =   'LGM002';
            return  FALSE;
        }
        
        // 写缓存
        // $data['id'] = $result;
        // $this->diaryListCacheModel->setGroupChatMessageCache($data['gid'], $result, $data);
        // 写列表
        // $this->diaryListCacheModel->addGroupChatIdToList($data['gid'], $result);
        return  $result;
    }
    
    public function getGroupChatMessageCache($gid, $id){
        /*$result = $this->diaryListCacheModel->getGroupChatMessageCache($gid, $id);
        if (!empty($result)){
            return $result;
        }*/
        
        $key      =   $this->groupChatMessageKeyPrefix. $gid;
        $where    =   array('id' => $id);
        $result =   Storage::getConditionData($key, $where);
        return  $result;
    }
    
    /**
     * 群聊天列表
     * @param number $start
     * @param number $length
     * @param unknown $gid
     * @param number $id
     * @param string $listModel
     * @return Ambigous <unknown, boolean, multitype:>
     */
    public function getGroupChatList($start = 0, $length = 20, $gid, $id = 0, $listModel = '')/*{{{*/
    {
        // 列表上拉下拉两种情况
        $conditions  =  array(
                'down'    =>    array(
                        'where'      =>   ' gid = '.$gid.' AND id < '.$id,
                        'orderBy'    =>   ' id DESC '
                        ),
                'up'    =>    array(
                        'where'      =>   ' gid = '.$gid.' AND id > '.$id,
                        'orderBy'    =>   ' id ASC '
                        ),
        );  
        
        // 默认情况
        $where  =   ' gid = '.$gid;
        $orderBy=   ' id DESC ';
        if ($id > 0){
            $start  =  0;
            $where  =  ' gid = '.$gid.' AND id > '.$id;
        }
        
        // 两种情况
        if ($conditions[$listModel]){
            $where    = $conditions[$listModel]['where'];
            $orderBy  = $conditions[$listModel]['orderBy'];
        }
        
        // if ($listModel == 'down' || $id == 0){
        if (false){
            // 是否初始化聊天记录的缓存列表
            $chatListCacheCtime = $this->diaryListCacheModel->getChatListCacheCtime($gid);
            if (intval($chatListCacheCtime) < 1){
                // 删除列表
                $this->diaryListCacheModel->delGroupChatIdList($gid);
            
                // 重建列表
                $chat_list = $this->rebuildChatListAndReturnOnePageDatas($gid, $start, $length);
                if ($chat_list){
                    $this->diaryListCacheModel->setChatListCacheCtime($gid);
                    return $chat_list;
                }
            }
            
            // 查询缓存列表
            $messageListIds = $this->diaryListCacheModel->getGroupChatList($gid, $id, $start, $length);
            if (!empty($messageListIds) && count($messageListIds) == $length ){
                foreach ($messageListIds as $val){
                    $tmp['id'] = $val;
                    $ids[] = $tmp;
                }
                return $ids;
            }
            
        }
        
        $key    =   $this->groupChatMessageKeyPrefix. $gid;
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);
        return  $result;
    }/*}}}*/

    public function getChatGroupListByGid($gid, $start=0, $length=20){
        $key    =   $this->groupChatMessageKeyPrefix. $gid;
        $where = 'gid='.$gid;
        $result =   Storage::getConditionManyData($key, $where, 'id desc', $start, $length);
        return  $result;
    }

    /**
     * 重建列表并返回一页数据
     * @param unknown $gid
     * @param unknown $start
     * @param unknown $length
     * @return multitype:
     */
    private function rebuildChatListAndReturnOnePageDatas($gid, $start, $length){
        $where  =   ' gid = '.$gid;
        $orderBy=   ' id DESC ';
        $key    =   $this->groupChatMessageKeyPrefix. $gid;
        $result =   Storage::getConditionManyData($key, $where, $orderBy, 0, 100);
        if ($result){
            $chatList = array_reverse($result);
            foreach ($chatList as $val){
                $this->diaryListCacheModel->addGroupChatIdToList($gid, $val['id']);
                $this->diaryListCacheModel->setGroupChatMessageCache($gid, $val['id'], $val);
            }
        }
        return  array_splice($result, $start, $length);
    }
    
    public function structurePendingRequestsData($param){
        $result = array(
                "id"        =>    "0",
                "gid"       =>    "0",
                "uid"       =>    "0",
                "linkid"    =>    "0",
                "status"    =>    "0",
                "time"      =>    "0",
                "content"   =>    "",
                "user"      =>    ""
        );
    
        isset($param['id'])        &&    $result['id']        =    strval($param['id']);
        isset($param['gid'])       &&    $result['gid']       =    strval($param['gid']);
        isset($param['uid'])       &&    $result['uid']       =    strval($param['uid']);
        isset($param['linkid'])    &&    $result['linkid']    =    strval($param['linkid']);
        isset($param['status'])    &&    $result['status']    =    strval($param['status']);
        isset($param['time'])      &&    $result['time']      =    strval($param['time']);
        isset($param['content'])   &&    $result['content']   =    strval($param['content']);
        $result['user'] = $this->autoUidModel->getUserInfo($result['uid'], '', AC::HOST_UID);
        return $result;
    }
    
    /**
     * 群用户返回数据结构
     * @param unknown $param
     * @param unknown $uid
     * @return multitype:string
     */
    public function structureChatUserData($param, $uid, $role = 0, $attribute){
        $result = array(
                'uid'          =>    strval($uid),
                'level'        =>    '1',
                'remark'       =>    '',
                'chat_num'     =>    '0',
                'last_time'    =>    '0',
                'activity'     =>    '1',
                'time'         =>    '0',
                'role'         =>    '0',
                'user'         =>    array()
        );
        isset($param['level'])     &&    $result['level']     =    strval($param['level']);
        isset($param['chat_num'])  &&    $result['chat_num']  =    strval($param['chat_num']);
        isset($param['last_time']) &&    $result['last_time'] =    strval($param['last_time']);
        isset($param['activity'])  &&    $result['activity']  =    strval($param['activity']);
        isset($param['time'])      &&    $result['time']      =    strval($param['time']);
        if ($attribute > 0 && $param['remark']) {
            $result['remark']    =    strval($param['remark']);
        }
        
        $result['role']      =    strval($role);
        $result['user']      =	  $this->autoUidModel->getUserInfo($uid);
        $result['user']['nickname']    =    $this->autoUidModel->getRemarkName($result['user']);
        return $result;
    }
    
    /**
     * 返回群信息结构
     * @param unknown $param
     * @return multitype:string
     */
    public function structureChatGroupData($param, $uid = 0){
        $result = array(
                'gid'           =>    '0',
                'uid'           =>    '0',
                'name'          =>    '',
                'category'      =>    '1',
                'introduction'  =>    '',
                'cover'         =>    array(),
                'member_num'    =>    '1',
                'max_member_num'=>    '1',
                'user_status'   =>    '0',
                'user_role'     =>    '0',
                'type'          =>    '1',
                'level'         =>    '1',
		'attribute'     =>    '0',
                'level_url'     =>    '',
                'time'          =>    '0',
                'remark'        =>    '',
                'gotype_gid'    =>    '0',
                'creator'       =>    ''
        );
        isset($param['gid'])            &&    $result['gid']            =    strval($param['gid']);
        isset($param['uid'])            &&    $result['uid']            =    strval($param['uid']);
        isset($param['name'])           &&    $result['name']           =    strval($param['name']);
        isset($param['category'])       &&    $result['category']       =    strval($param['category']);
        isset($param['introduction'])   &&    $result['introduction']   =    strval($param['introduction']);
        isset($param['cover'])          &&    $result['cover']          =    strval($param['cover']);
        isset($param['member_num'])     &&    $result['member_num']     =    strval($param['member_num']);
        isset($param['max_member_num']) &&    $result['max_member_num'] =    strval($param['max_member_num']);
        isset($param['type'])           &&    $result['type']           =    strval($param['type']);
        isset($param['level'])          &&    $result['level']          =    strval($param['level']);
        isset($param['attribute'])      &&    $result['attribute']      =    strval($param['attribute']);
        isset($param['time'])           &&    $result['time']           =    strval($param['time']);
        $result['max_member_num'] = ExpLevel::$grouplevelAddLimit[$result['level']];
        // 官方群最大用户数
        if (in_array($result['gid'], AC::$officialGids)){
            $result['max_member_num'] = AC::$officialMemberNum[$result['gid']];
        }
        // 群等级显示页面地址
        if (intval($result['gid']) > 0){
            $result['level_url'] = AC::getProtocolUriByOS(AC::$level_url_prefix)."?gid=".$result['gid']."&t=".AC::SERVER_TIME;
        }
        $result['creator'] = $this->autoUidModel->getUserInfo($result['uid'], '', AC::HOST_UID);
        $result['creator'] = $this->autoUidModel->checkIsMe($result['creator']);
        $result['creator']['nickname']    =    $this->autoUidModel->getRemarkName($result['creator']);
        // 群封面
        $covers = $param['cover'];
        if(!empty($covers)){
            $covers = json_decode($covers,true);
            $data  = array();
            $base  = AC::getProtocolUriByOS(AC::$cdn_url_img);
            foreach($covers as $pic){
                if (empty($pic)){
                    continue;
                }
                $data[] =  $base.$pic;
            }
            $result['cover'] = $data;
        }
        
        $linkInfo = $this->getGroupUserLinkInfo($uid, $result['gid']);
        isset($linkInfo['status'])    &&    $result['user_status'] = strval($linkInfo['status']);
        isset($linkInfo['role'])      &&    $result['user_role']   = strval($linkInfo['role']);
        
        // 群中备注
        $chat_group_user_info = $this->getChatUserInfoById($uid, $linkInfo, $result);
        if (!empty($chat_group_user_info)){
            $result['remark'] = strval($chat_group_user_info['remark']);
        }
        
        // 群升级状态
        if ($result['attribute'] != $this->familyGroup && $result['attribute'] != $this->collegeGroup){
            $result['attribute'] = '0';
        }

        // 最后发言时间、内容
        $result['lastContent'] = '';
        $result['lastTime']    = '';
    
        return $result;
    }
    
}

